package main;

import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import java.util.UUID;

import org.json.simple.JSONObject;

public class ServerGlobals {
	public static final String LAST_ACTIVE_TIME = "last_active_timestamp";
	public static final Long INACTIVE_TIME_TO_ERASE = new Long(500000);
	private static ServerGlobals instance = null;
	private JSONObject _sessions;
	private Hashtable<Long, String> _sessionActiveTimebyTime;
	private Hashtable<String, Long> _sessionActiveTimeById;

	protected ServerGlobals() {
		_sessions = new JSONObject();
		_sessionActiveTimebyTime = new Hashtable<>();
		_sessionActiveTimeById = new Hashtable<>();
	}

	public JSONObject getSession(String sessionId) {
		JSONObject ret = null;
		synchronized (_sessions) {
			ret = (JSONObject) this._sessions.get(sessionId);
		}

		if (ret != null) {
			Long time = (System.currentTimeMillis());
			this._sessionActiveTimebyTime.remove(this._sessionActiveTimeById
					.get(sessionId));
			this._sessionActiveTimebyTime.put(time, sessionId);
			this._sessionActiveTimeById.put(sessionId, time);
		}
		return ret;
	}

	public static ServerGlobals getInstance() {
		if (instance == null) {
			instance = new ServerGlobals();
		}
		return instance;
	}

	public void deleteSession(String sessionId) {
		_sessionActiveTimebyTime.remove(_sessionActiveTimeById.get(sessionId));
		_sessionActiveTimeById.remove(sessionId);
		synchronized (_sessions) {
			_sessions.remove(sessionId);
		}
	}

	@SuppressWarnings("unchecked")
	public String generateSessionId() {
		String sessionId = UUID.randomUUID().toString();
		while (this._sessions.containsKey(sessionId)) {
			sessionId = UUID.randomUUID().toString();
		}
		Long time = (System.currentTimeMillis());
		synchronized (_sessions) {
			this._sessions.put(sessionId, new JSONObject());
		}

		this._sessionActiveTimebyTime.put(time, sessionId);
		this._sessionActiveTimeById.put(sessionId, time);
		return sessionId;
	}

	

	public synchronized boolean sessionIdExists(String sessionId) {
		return this._sessions.containsKey(sessionId);
	}
}
